﻿#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion

using System;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Reflection;

namespace Newtonsoft.Utilities.Logging
{
  public class TextExceptionFormatter : ExceptionFormatter
  {
    private readonly TextWriter _writer;
    private int _innerDepth;

    public TextExceptionFormatter(TextWriter writer, Exception exception)
      : base(exception)
    {
      if (writer == null)
        throw new ArgumentNullException("writer");

      _writer = writer;
    }

    public TextWriter Writer
    {
      get { return _writer; }
    }

    protected virtual void Indent()
    {
      for (int i = 0; i < _innerDepth; i++)
      {
        Writer.Write("\t");
      }
    }

    private void IndentAndWriteLine(string format, params object[] arg)
    {
      Indent();
      Writer.WriteLine(format, arg);
    }

    protected override void WriteAdditionalInfo(NameValueCollection additionalInformation)
    {
      Writer.WriteLine("Additional Info:");
      Writer.WriteLine();
      foreach (string str in additionalInformation.AllKeys)
      {
        Writer.Write(str);
        Writer.Write(" : ");
        Writer.Write(additionalInformation[str]);
        Writer.Write("\n");
      }
    }

    protected override void WriteDateTime(DateTime utcNow)
    {
      string str = utcNow.ToLocalTime().ToString("G", DateTimeFormatInfo.InvariantInfo);
      Writer.WriteLine(str);
    }

    protected override void WriteDescription()
    {
      string str = string.Format(CultureInfo.InvariantCulture, "An exception of type '{0}' occurred and was caught.", new object[] { base.Exception.GetType().FullName });
      Writer.WriteLine(str);
      var str2 = new string('-', str.Length);
      Writer.WriteLine(str2);
    }

    protected override void WriteException(Exception exceptionToFormat, Exception outerException)
    {
      if (outerException != null)
      {
        _innerDepth++;
        Indent();
        string innerException = "Inner Exception";
        var str2 = new string('-', innerException.Length);
        Writer.WriteLine(innerException);
        Indent();
        Writer.WriteLine(str2);
        base.WriteException(exceptionToFormat, outerException);
        _innerDepth--;
      }
      else
      {
        base.WriteException(exceptionToFormat, outerException);
      }
    }

    protected override void WriteExceptionType(Type exceptionType)
    {
      IndentAndWriteLine("Type : {0}", new object[] { exceptionType.AssemblyQualifiedName });
    }

    protected override void WriteHelpLink(string helpLink)
    {
      IndentAndWriteLine("Help link : {0}", new object[] { helpLink });
    }

    protected override void WriteMessage(string message)
    {
      IndentAndWriteLine("Message : {0}", new object[] { message });
    }

    protected override void WriteMemberInfo(MemberInfo memberInfo, object value)
    {
      Indent();
      Writer.Write(memberInfo.Name);
      Writer.Write(" : ");
      Writer.WriteLine(value);
    }

    protected override void WriteSource(string source)
    {
      IndentAndWriteLine("Source : {0}", new object[] { source });
    }

    protected override void WriteStackTrace(string stackTrace)
    {
      Indent();
      Writer.Write("Stack Trace");
      Writer.Write(" : ");
      if (string.IsNullOrEmpty(stackTrace))
      {
        Writer.WriteLine("The stack trace is unavailable.");
      }
      else
      {
        string str2 = stackTrace.Replace("\n", "\n" + new string('\t', _innerDepth));
        Writer.WriteLine(str2);
        Writer.WriteLine();
      }
    }
  }
}